package com.dmg.sp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dmg.sp.dao.MenuMapper;
import com.dmg.sp.entity.Menu;
import com.dmg.sp.entity.MyUserDetails;
import com.dmg.sp.entity.Role;
import com.dmg.sp.service.MenuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Slf4j
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;


    /**
     * 获取所有菜单
     * @return
     */
    @Override
    public List<Menu> getMenuList() {
        List<Menu>res=new ArrayList<>();
        List<Menu>list=menuMapper.getMenuList();
        //递归放入 子菜单
        for (Menu x : list) {
            if(x.getIsType().equals("2")){
                //如果是按钮 直接跳过 因为是 最后一层
                continue;
            }
            dfs(x,list);
            if(x.getParentId()==0){
                //只把一级菜单放入集合中 其他级别的菜单都在一级菜单的子集中
                res.add(x);
            }
        }
        return res;
    }


    /**
     * 添加菜单
     * @param menu
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addMenu(Menu menu) {
        //根据权限查询是否存在
        if(getByAuth(menu.getAuth())!=null){
            throw new RuntimeException("权限已存在");
        }
        menu.setCreateTime(new Date());
        menuMapper.insert(menu);
    }



    /**
     * 修改菜单
     * @param menu
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void editMenu(Menu menu) {
        Menu bean=menuMapper.selectById(menu.getId());
        if(bean==null){
            throw new RuntimeException("菜单不存在");
        }
        Menu item=getByAuth(menu.getAuth());
        if(item!=null && !item.getAuth().equals(bean.getAuth())){
            //如果不是当前菜单的权限,并且已存在 那么抛出异常
            throw new RuntimeException("权限已存在");
        }
        menuMapper.updateById(menu);
    }


    /**
     * 删除菜单
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteMenu(Integer id) {
        //判断菜单是否存在
        if(menuMapper.selectById(id)==null){
            throw new RuntimeException("菜单不存在");
        }
        //判断当前是否有子集,如果有子集 不允许删除
        if(getPIdCount(id)>0){
            throw new RuntimeException("当前菜单下,还有子集,请先删除子集");
        }
        //删除菜单关联的角色
        menuMapper.deleteRole(id);
        //删除菜单
        menuMapper.deleteById(id);
    }


    /**
     * 根据菜单id 查看详情
     * @param id
     */
    @Override
    public Menu getMenuById(Integer id) {
        return menuMapper.selectById(id);
    }

    /**
     * 查看角色对应的权限
     * @return
     */
    @Override
    public List<String> getRoleAuth(Integer roleId) {
        return menuMapper.getRoleAuth(roleId);
    }





    /**
     * 递归放入父级中
     * @param x
     * @param list
     */
    private void dfs(Menu x,List<Menu>list){
        for (Menu menu : list) {
            if(menu.getParentId().equals(x.getId())){
                //如果子集 匹配上了父级 那么把子集放入父级中
                List<Menu> children = x.getChildren();
                if(CollectionUtils.isEmpty(children)){
                    children=new ArrayList<>();
                }
                children.add(menu);
                x.setChildren(children);
            }
        }
    }

    /**
     * 根据权限获取菜单信息
     * @return
     */
    private Menu getByAuth(String auth){
        QueryWrapper<Menu> queryWrapper=new QueryWrapper();
        queryWrapper.eq("auth",auth);
        Menu x=menuMapper.selectOne(queryWrapper);
        return x;
    }

    /**
     * 获取是否有子集
     * @return
     */
    private Long getPIdCount(Integer parentId){
        QueryWrapper<Menu> queryWrapper=new QueryWrapper();
        queryWrapper.eq("parent_id",parentId);
        return menuMapper.selectCount(queryWrapper);
    }


    /**
     * 获取当前登录人的菜单信息
     * @return
     */
    @Override
    public List<Menu> getMyMenu() {
        //从认证信息上下文中 获取用户权限
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication.getPrincipal() instanceof MyUserDetails){
            MyUserDetails myUserDetails =(MyUserDetails) authentication.getPrincipal();
            return myUserDetails.getUser().getMenu();
        }
        return new ArrayList<>();
    }

}
